package cn.krui.project.controller.system;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.krui.helper.bean.AppResult;
import cn.krui.helper.bean.DataArray;
import cn.krui.helper.bean.SysLoginInfo;
import cn.krui.helper.db.DBHelper;
import cn.krui.helper.db.SQL;
import cn.krui.project.bean.system.sys_menu.sys_menu;
import cn.krui.project.bean.system.sys_permissions.sys_permissions;
import cn.krui.project.service.system.SysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; 

/**
 * @program: project-system
 * @description: 菜单模块
 * @author: admin
 * @create: 2019-10-10 16:05
 **/
@Api(tags = "管理-菜单", description = "系统菜单模块接口", hidden = true)
@RestController
@RequestMapping("/system/sysmenu")
@CrossOrigin
public class SysMenuController extends SystemBaseController {

	@Autowired
	private SysMenuService sysMenuService;
	@Autowired
	private DBHelper dbHelper;
	private final String EQUALS_COMMA = ",";
	/**
	 * 菜单列表
	 */
	@PostMapping(value = "/getSysMenuList")
	@ApiOperation(value = "获取菜单列表", httpMethod = "POST")
	public AppResult<sys_menu> getSysDeptList(
			@ApiParam(value = "父级id", required = false) @RequestParam(value = "pid", required = false) String pid,
			@ApiParam(value = "菜单名称", required = false) @RequestParam(value = "menu_name", required = false) String menu_name,
			@ApiParam(value = "级别", required = false) @RequestParam(value = "level", required = false) String level,
			@ApiParam(value = "菜单类型", required = false) @RequestParam(value = "menu_type", required = false) String menu_type,
			@ApiParam(value = "适用类型", required = false) @RequestParam(value = "user_type", required = false) String user_type) {
		AppResult<sys_menu> app = new AppResult<sys_menu>();
		sys_menu sysMenu = new sys_menu();
		if (!StringUtils.isEmpty(pid)) {
			sysMenu.setPid(Integer.parseInt(pid));
		}
		if (!StringUtils.isEmpty(menu_name)) {
			sysMenu.setMenu_name(menu_name);
		}
		if (!StringUtils.isEmpty(level)) {
			sysMenu.setLevel(Integer.parseInt(level));
		}
		if (!StringUtils.isEmpty(menu_type)) {
			sysMenu.setMenu_type(Integer.parseInt(menu_type));
		}
		if (!StringUtils.isEmpty(user_type)) {
			sysMenu.setUser_type(Integer.parseInt(user_type));
		}
		List<sys_menu> sysMenusList = sysMenuService.selectSysMenuList(sysMenu);
		///////////////////// 过滤当前没有权限的菜单//////////////////
		List<sys_menu> copyMenuList = new ArrayList<>();
		Set<String> role_menus = new HashSet<>();
		for (String str : getUser().getRole_menu().split(",")) {
			role_menus.add(str);
		}
		for (sys_menu sys_menu : sysMenusList) {
			if(getUser().getUid()==getUser().getGroup_id()){
				//超管特权
				copyMenuList.add(sys_menu);
				continue;
			}
			if (role_menus.contains(sys_menu.getCode())) {
				copyMenuList.add(sys_menu);
				role_menus.remove(sys_menu.getCode());
			}
		}
		sysMenusList.clear();
		////////////////////////////////////
		List<sys_menu> menusList = new ArrayList<>();
		String codes = ",";
		// 循环递归获取子解点数据
		for (sys_menu nav : copyMenuList) {
			List<sys_menu> child = this.getChild(nav.getId(), nav.getMenu_name(), sysMenu.getMenu_type());
			nav.setChildren(child);
			menusList.add(nav);
			if (child.size() > 0) {
				codes += nav.getCode() + ",";
			}
		}
		app.ok();
		DataArray<sys_menu> list = new DataArray<>();
		list.setDataList(menusList);
		list.setDataCount(copyMenuList.size());
		app.setDataArray(list);
		app.setExt(codes);
		app.setMsg("获取成功");
		return app;
	}

	/**
	 * 获取子节点
	 * 
	 * @param id      父节点id
	 * @param allMenu 所有菜单列表
	 * @return 每个根节点下，所有子菜单列表
	 */
	public List<sys_menu> getChild(Integer id, String pName, Integer menuType) {
		List<sys_menu> list = new ArrayList<sys_menu>();
		// 子菜单
		SQL.SelectSQL sql = SQL.select("*").from("qr_sys_menu").where("pid=#{id}").orderBy("sort desc")
				.addParameter("id", id);
		if (menuType != null) {
			sql.where("menu_type=" + menuType);
		}
		List<sys_menu> childList = dbHelper.select(sql, sys_menu.class);
		///////////////////////////// 过滤当前没有权限的菜单///////////////////////////
		List<sys_menu> copyMenuList = new ArrayList<>();
		Set<String> roleMenus = new HashSet<>(100);
		for (String str : getUser().getRole_menu().split(EQUALS_COMMA)) {
			roleMenus.add(str);
		}
		for (sys_menu sysMenu : childList) {
			if(getUser().getUid()==getUser().getGroup_id()){
				//超管特权
				copyMenuList.add(sysMenu);
				continue;
			}
			if (roleMenus.contains(sysMenu.getCode())) {
				copyMenuList.add(sysMenu);
				roleMenus.remove(sysMenu.getCode());
			}
		}
		childList.clear();
		/////////////////////// 过滤当前没有权限的菜单////////////////////////////////////////
		for (sys_menu nav : copyMenuList) {
			nav.setP_name(pName);
			nav.setChildren(this.getChild(nav.getId(), nav.getMenu_name(), menuType));
			list.add(nav);
		}

		return list;
	}

	/**
	 * 添加菜单
	 */
	@PostMapping(value = "/addSysMenu")
	@ApiOperation(value = "添加菜单", httpMethod = "POST")
	public AppResult<?> addSysMenu(
			@ApiParam(value = "菜单名称", required = true) @RequestParam(value = "menu_name", required = true) String menu_name,
			@ApiParam(value = "菜单路径", required = true) @RequestParam(value = "link_url", required = false) String link_url,
			@ApiParam(value = "父级id", required = true) @RequestParam(value = "pid", required = true) String pid,
			@ApiParam(value = "排序", required = true) @RequestParam(value = "sort", required = true) String sort) {
		AppResult<Object> app = new AppResult<>();
		sys_menu sysMenu = new sys_menu();
		sysMenu.setMenu_name(menu_name);
		sysMenu.setLink_url(link_url);
		if (!StringUtils.isEmpty(pid)) {
			sysMenu.setPid(Integer.parseInt(pid));
			sys_menu psysMenu = new sys_menu();
			SQL.SelectSQL sql = SQL.select("*").from("qr_sys_menu").where("id=#{id}").addParameter("id", pid);
			psysMenu = dbHelper.selectOne(sql, sys_menu.class);
			if (!StringUtils.isEmpty(psysMenu)) {
				sysMenu.setParent_code(psysMenu.getMenu_name());
				sysMenu.setLevel(psysMenu.getLevel() + 1);
			}
		} else {
			sysMenu.setPid(0);
			sysMenu.setLevel(1);
		}
		if (!StringUtils.isEmpty(sort)) {
			sysMenu.setSort(Integer.parseInt(sort));
		}
		sysMenu.setStatus(1);
		sysMenu.setExpanded(1);
		Integer i = sysMenuService.addSysMenu(sysMenu);
		if (i > 0) {
			app.ok();
			app.setMsg("添加成功");
		} else {
			app.no("");
			app.setMsg("添加失败");
		}
		return app;
	}

	/**
	 * 编辑菜单
	 */
	@PostMapping(value = "/updateSysMenu")
	@ApiOperation(value = "编辑菜单", httpMethod = "POST")
	public AppResult<?> updateSysMenu(
			@ApiParam(value = "id", required = true) @RequestParam(value = "id", required = true) String id,
			@ApiParam(value = "菜单名称", required = true) @RequestParam(value = "menu_name", required = true) String menu_name,
			@ApiParam(value = "菜单路径", required = true) @RequestParam(value = "link_url", required = false) String link_url,
			@ApiParam(value = "父级id", required = true) @RequestParam(value = "pid", required = true) String pid,
			@ApiParam(value = "排序", required = true) @RequestParam(value = "sort", required = true) String sort) {
		AppResult<Object> app = new AppResult<>();
		sys_menu sysMenu = new sys_menu();
		sysMenu.setMenu_name(menu_name);
		sysMenu.setLink_url(link_url);
		if (!StringUtils.isEmpty(pid)) {
			if (id.equals(pid)) {
				app.no("");
				app.setMsg("更新失败,上级菜单不能与当前菜单相同");
				return app;
			}
			sysMenu.setPid(Integer.parseInt(pid));
			sys_menu psysMenu = new sys_menu();
			SQL.SelectSQL sql = SQL.select("*").from("qr_sys_menu").where("id=#{id}").addParameter("id", pid);
			psysMenu = dbHelper.selectOne(sql, sys_menu.class);
			sysMenu.setParent_code(psysMenu.getMenu_name());
			sysMenu.setLevel(psysMenu.getLevel() + 1);
		} else {
			sysMenu.setPid(0);
			sysMenu.setLevel(1);
		}
		if (!StringUtils.isEmpty(sort)) {
			sysMenu.setSort(Integer.parseInt(sort));
		}
		sysMenu.setStatus(1);
		sysMenu.setId(Integer.parseInt(id));
		Integer i = sysMenuService.updateSysMenu(sysMenu);
		if (i > 0) {
			app.ok();
			app.setMsg("编辑成功");
		} else {
			app.no("");
			app.setMsg("编辑失败");
		}
		return app;
	}

	/**
	 * 删除菜单
	 */
	@PostMapping(value = "/deleteSysMenu")
	@ApiOperation(value = "删除菜单", httpMethod = "POST")
	public AppResult<?> deleteSysMenu(
			@ApiParam(value = "主键id", required = true) @RequestParam(value = "id", required = true) String id) {
		AppResult<Object> app = new AppResult<>();
		SQL.SelectSQL sql = SQL.select("id").from("qr_sys_menu").where("pid=#{id}").addParameter("id", id);
		List<Map<String, Object>> list = dbHelper.select(sql);
		if (list.size() > 0) {
			app.no("");
			app.setMsg("存在子菜单,删除失败");
			return app;
		}

		Integer i = sysMenuService.deleteSysMenu(id);
		if (i > 0) {
			app.ok();
			app.setMsg("删除成功");
		} else {
			app.no("");
			app.setMsg("删除失败");
		}

		return app;
	}

	/**
	 * 前端用户菜单 zc 2019-12-05
	 * 
	 * @return
	 */
	@PostMapping(value = "/UserMenuTree")
	@ApiOperation(value = "前端用户菜单", httpMethod = "POST")
	public AppResult<?> UserMenuTree() {
		AppResult<Object> app = new AppResult<>();
		SysLoginInfo sysLoginInfo = getUser();
		List<sys_menu> _sys_menus = sysMenuService.selectSysMenuListAll();
		String[] menus = sysLoginInfo.getRole_menu().split(",");
		List<String> _role_menus = new ArrayList<String>(menus.length);
		Collections.addAll(_role_menus, menus);
		Map<Integer, sys_menu> topmap = new LinkedHashMap<>();
		for (int i = _sys_menus.size(); i > 0; i--) {
			Object _rm_code = _sys_menus.get(i - 1).getCode();
			int index = _role_menus.indexOf(_rm_code);
			if (index >= 0) {
				sys_menu co = _sys_menus.get(i - 1);
				if (co.getMenu_type() == 1) {
					_role_menus.remove(index);
				}
//					co.setCode_aes(AESUtil.encrypt(co.getCode()));
				co.setCode_aes(co.getCode());
				int pid = co.getPid();
				if (pid == 0) {
					int cid = co.getId();
					if (!topmap.containsKey(cid)) {
						co.setChildren(new ArrayList<>());
						topmap.put(cid, co);
					}
				} else {
					topmap.get(pid).getChildren().add(co);
				}
			} else{
				_sys_menus.remove(i - 1);
			}
		}
		_sys_menus.clear();
		_role_menus.clear();
		for (Map.Entry<Integer, sys_menu> entry : topmap.entrySet()) {
			_sys_menus.add(entry.getValue());
		}
		topmap.clear();
		app.setDataSingle(_sys_menus);
		app.ok();
		return app;
	}

	/**
	 * 前端用户权限 admin 2019-12-05
	 * 
	 * @return
	 */
	@PostMapping(value = "/UserMenuPers")
	@ApiOperation(value = "前端用户权限", httpMethod = "POST")
	public AppResult<sys_permissions> UserMenuPers(
			@ApiParam(value = "菜单标识", required = true) @RequestParam(value = "menu_id", required = true) String menu_id) {
		AppResult<sys_permissions> app = new AppResult<sys_permissions>();
		SysLoginInfo sysLoginInfo = getUser();
		String menus = sysLoginInfo.getRole_menu();
//			menu_id = AESUtil.decrypt(menu_id);
		if (menus.indexOf(menu_id) < 0) {
			app.no("没有权限");
			return app;
		}
		Map<String, Object> params = new HashMap<>(1);
		params.put("menu_id", menu_id.substring(2));
		List<sys_permissions> list = dbHelper.select("*", "qr_sys_permissions", "menu_id=#{menu_id}", "", params,
				sys_permissions.class);
		String permissions = sysLoginInfo.getRole_permissions();
		for (int i = list.size(); i > 0; i--) {
			sys_permissions item = list.get(i - 1);
			if (permissions.indexOf(item.getPermissions_code()) < 0) {
				list.remove(i - 1);
			}
		}
		DataArray<sys_permissions> dataArray = new DataArray<sys_permissions>();
		dataArray.setDataList(list);
		dataArray.setDataCount(list.size());
		app.setDataArray(dataArray);
		return app;
	}
}
